﻿//https://leetcode.cn/problems/lru-cache/?envType=study-plan-v2&envId=top-100-liked

class LRUCache {
public:
    LRUCache(int capacity)
        :_capacity(capacity)
    {

    }

    int get(int key) {
        //判断key是否存在
        auto ret = _hash.find(key);
        if (ret != _hash.end())
        {
            //把key对应的节点挪到链表的头部
            LtIter it = ret->second;  //找到它的节点--hash表实现O(1)出查找
            //转移节点
            _LURlist.splice(_LURlist.begin(), _LURlist, it);

            return it->second;
        }

        return -1;
    }

    void put(int key, int value)
    {
        //判断是更新还是新增
        auto ret = _hash.find(key);
        if (ret == _hash.end())
        {
            //新增
            //判断是否满了，满了要删除最近最少使用的数据
            if (_capacity == _hash.size())
            {
                //删除LRU的数据
                pair<int, int> back = _LURlist.back();
                _hash.erase(back.first);
                _LURlist.pop_back();
            }

            //没满
            _LURlist.push_front(make_pair(key, value));
            _hash[key] = _LURlist.begin();
        }
        else
            //更新
        {
            LtIter it = ret->second;  //找到它的节点--hash表实现O(1)出查找
            it->second = value;
            //转移节点
            _LURlist.splice(_LURlist.begin(), _LURlist, it);
        }

    }
private:
    size_t _capacity;
    typedef list<pair<int, int>>::iterator LtIter;
    unordered_map<int, LtIter> _hash;
    list<pair<int, int>> _LURlist;
};
/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */